package org.mindrive.system.web.system;

import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.mindrive.system.annotation.LogOperation;
import org.mindrive.system.collection.system.RoleEntity;
import org.mindrive.system.core.Result;
import org.mindrive.system.parameter.BaseSearchParameter;
import org.mindrive.system.parameter.system.RoleParameter;
import org.mindrive.system.parameter.system.RolePeopleParameter;
import org.mindrive.system.service.BaseService;
import org.mindrive.system.service.system.PermissionService;
import org.mindrive.system.service.system.RoleService;
import org.mindrive.system.web.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

@Api(tags = {"权限设置"})
@RestController
@RequestMapping("/permissions")
@Slf4j
public class PermissionController extends BaseController {

    @Autowired
    private RoleService roleService;

    @Autowired
    private PermissionService menuService;

    @LogOperation(type = BaseService.AUDIT_EVENT_TYPE_CREATE, event = "新建角色")
    @ApiOperation(value = "新建角色", notes = "新建角色")
    @ApiImplicitParam(name = "authorization", value = "令牌", required = true, paramType = "header")
    @PostMapping(path = "/roles")
    public Result createRole(@Validated @RequestBody RoleParameter parameter, BindingResult bindingResult) {
        log.info("新建角色开始。[{}]", JSON.toJSONString(parameter));
        Result result = new Result();
        try {
            validParams(bindingResult);
            RoleEntity role = roleService.create(parameter);
            result = Result.ok(role);
        } catch (Exception ex) {

            log.error("新建角色失败。", ex);
            result = Result.error(ex.getMessage());
        }

        log.info("新建角色结束。");
        return result;
    }

    @LogOperation(type = BaseService.AUDIT_EVENT_TYPE_SEARCH, event = "查询角色")
    @ApiOperation(value = "查询角色", notes = "查询角色")
    @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "令牌", required = true)
    @PostMapping(path = "/roles/search")
    public Result getRoles(@RequestBody BaseSearchParameter parameter) {

        log.info("查询角色开始。[{}]", JSON.toJSONString(parameter));
        Result result = new Result();
        try {
            Map data = roleService.searchRoles(parameter);
            result = Result.ok(data);
        } catch (Exception ex) {

            log.error("查询角色失败。", ex);
            result = Result.error(ex.getMessage());
        }
        log.info("查询角色结束。");
        return result;
    }

    @LogOperation(type = BaseService.AUDIT_EVENT_TYPE_MODIFY, event = "修改角色")
    @ApiOperation(value = "修改角色", notes = "修改角色")
    @ApiImplicitParam(name = "authorization", value = "令牌", required = true, paramType = "header")
    @PutMapping(path = "/roles/{id}")
    public Result updateRole(@PathVariable(value = "id") String id, @Validated @RequestBody RoleParameter parameter,
            BindingResult bindingResult) {
        log.info("修改角色开始。[{}],[{}]", id, JSON.toJSONString(parameter));
        Result result = new Result();
        try {
            validParams(bindingResult);
            roleService.update(id, parameter);
            result = Result.ok();
        } catch (Exception ex) {

            log.error("修改角色失败。", ex);
            result = Result.error(ex.getMessage());
        }

        log.info("修改角色结束。");
        return result;
    }

    @LogOperation(type = BaseService.AUDIT_EVENT_TYPE_SEARCH, event = "取得角色详细")
    @ApiOperation(value = "取得角色详细", notes = "取得角色详细")
    @ApiImplicitParam(name = "authorization", value = "令牌", required = true, paramType = "header")
    @GetMapping(path = "/roles/{id}")
    public Result detail(@PathVariable(value = "id") String id) {
        log.info("取得角色详细开始。[{}]", id);
        Result result = new Result();
        try {
            RoleEntity data = roleService.detail(id);
            result = Result.ok(data);
        } catch (Exception ex) {

            log.error("取得角色详细失败。", ex);
            result = Result.error(ex.getMessage());
        }

        log.info("取得角色详细结束。");
        return result;
    }

    @LogOperation(type = BaseService.AUDIT_EVENT_TYPE_DELETE, event = "删除角色")
    @ApiOperation(value = "删除角色", notes = "删除角色")
    @ApiImplicitParam(name = "authorization", value = "令牌", required = true, paramType = "header")
    @DeleteMapping(path = "/roles/{id}")
    public Result deleteRole(@PathVariable(value = "id") String id) {
        log.info("删除角色开始。[{}]", id);
        Result result = new Result();
        try {
            roleService.delete(id);
            result = Result.ok();
        } catch (Exception ex) {
            log.error("删除角色失败。", ex);
            result = Result.error(ex.getMessage());
        }

        log.info("删除角色结束。");
        return result;
    }

    @LogOperation(type = BaseService.AUDIT_EVENT_TYPE_SEARCH, event = "取得权限树")
    @ApiOperation(value = "取得权限树", notes = "取得权限树")
    @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "令牌", required = true)
    @PostMapping(path = "/search")
    public Result getPermissions() {
        log.info("取得权限树开始。");
        Result result = new Result();
        try {
            List<Map<String, Object>> tree = menuService.tree();
            result = Result.ok(tree);
        } catch (Exception ex) {
            log.error("取得权限树失败。", ex);
            result = Result.error(ex.getMessage());
        }
        log.info("取得权限树结束。");
        return result;
    }

    @LogOperation(type = BaseService.AUDIT_EVENT_TYPE_MODIFY, event = "给角色授权")
    @ApiOperation(value = "给角色授权", notes = "给角色授权")
    @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "令牌", required = true)
    @PutMapping(path = "/{id}/permissions")
    public Result setPermissions(@PathVariable(value = "id") String id, @RequestBody List<String> permissions) {
        log.info("给角色授权开始。[{}],[{}]", id, JSON.toJSONString(permissions));
        Result result = new Result();
        try {
            roleService.setPermissions(id, permissions);
            result = Result.ok();
        } catch (Exception ex) {

            log.error("给角色授权失败。", ex);
            result = Result.error(ex.getMessage());
        }
        log.info("给角色授权结束。");
        return result;
    }

    @LogOperation(type = BaseService.AUDIT_EVENT_TYPE_SEARCH, event = "查找角色的成员")
    @ApiOperation(value = "查找角色的成员", notes = "查找角色的成员")
    @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "令牌", required = true)
    @PostMapping(path = "/roles/{id}/users")
    public Result searchUsersForRole(@PathVariable(value = "id") String id,
            @RequestBody BaseSearchParameter parameter) {
        log.info("查找角色的成员开始。[{}],[{}]", id, JSON.toJSONString(parameter));
        Result result = new Result();
        try {
            Map<String, Object> data = roleService.getUsersForRole(id, parameter);
            result = Result.ok(data);
        } catch (Exception ex) {
            log.error("查找角色的成员失败。", ex);
            result = Result.error(ex.getMessage());
        }
        log.info("查找角色的成员结束。");
        return result;
    }

    @LogOperation(type = BaseService.AUDIT_EVENT_TYPE_MODIFY, event = "设置角色某成员为主管人员")
    @ApiOperation(value = "设置角色某成员为主管人员", notes = "设置角色某成员为主管人员")
    @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "令牌", required = true)
    @PostMapping(path = "/roles/officerInCharge")
    public Result officerInCharge(@RequestBody RolePeopleParameter parameter){
        log.info("设置角色某成员为主管人员开始。[{}]", JSON.toJSONString(parameter));
        Result result = new Result();
        try {
            roleService.officerInCharge(parameter);
            result = Result.ok();
        } catch (Exception ex) {

            log.error("设置角色某成员为主管人员失败。", ex);
            result = Result.error(ex.getMessage());
        }
        log.info("查找没有角色的成员结束。");
        return result;
    }

    @LogOperation(type = BaseService.AUDIT_EVENT_TYPE_SEARCH, event = "查找没有角色的成员")
    @ApiOperation(value = "查找没有角色的成员", notes = "查找没有角色的成员")
    @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "令牌", required = true)
    @PostMapping(path = "/roles/{id}/no-users")
    public Result searchMembersForNoRole(@PathVariable(value = "id") String id,
            @RequestBody BaseSearchParameter parameter) {
        log.info("查找没有角色的成员开始。[{}],[{}]", id, JSON.toJSONString(parameter));
        Result result = new Result();
        try {
            Map<String, Object> data = roleService.getUsersForNoRole(id, parameter);
            result = Result.ok(data);
        } catch (Exception ex) {

            log.error("查找没有角色的成员失败。", ex);
            result = Result.error(ex.getMessage());
        }
        log.info("查找没有角色的成员结束。");
        return result;
    }

    @LogOperation(type = BaseService.AUDIT_EVENT_TYPE_MODIFY, event = "给角色添加成员")
    @ApiOperation(value = "给角色添加成员", notes = "给角色添加成员")
    @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "令牌", required = true)
    @PostMapping(path = "/roles/{id}/add-users")
    public Result addMembersForRole(@PathVariable(value = "id") String id, @RequestBody List<String> employeeIds) {
        log.info("给角色添加成员开始。[{}],[{}]", id, JSON.toJSONString(employeeIds));
        Result result = new Result();
        try {
            roleService.addUsersForRole(id, employeeIds);
            result = Result.ok();
        } catch (Exception ex) {

            log.error("给角色添加成员失败。", ex);
            result = Result.error(ex.getMessage());
        }
        log.info("给角色添加成员结束。");
        return result;
    }

    @LogOperation(type = BaseService.AUDIT_EVENT_TYPE_MODIFY, event = "给角色删除成员")
    @ApiOperation(value = "给角色删除成员", notes = "给角色删除成员")
    @ApiImplicitParam(paramType = "header", dataType = "String", name = "authorization", value = "令牌", required = true)
    @PostMapping(path = "/roles/{id}/delete-users")
    public Result deleteMembersForRole(@PathVariable(value = "id") String id, @RequestBody List<String> employeeIds) {
        log.info("给角色删除成员开始。[{}],[{}]", id, JSON.toJSONString(employeeIds));
        Result result = new Result();
        try {
            roleService.deleteUsersForRole(id, employeeIds);
            result = Result.ok();
        } catch (Exception ex) {

            log.error("给角色删除成员失败。", ex);
            result = Result.error(ex.getMessage());
        }
        log.info("给角色删除成员结束。");
        return result;
    }


}
